﻿using System;
using System.Collections.Generic;
using UnityEngine;

namespace Z1029.PhiPlayer.OpenSource
{
    public class JudgementLine : MonoBehaviour
    {
        public float speed, alpha;
        public SpeedEvent[] speeds;
        public ValueSet[] moveEvents;
        public ValueSet[] rotateEvents;
        public ValueSet[] alphaEvents;
        public float bpm;
        public Color AP, FC;
        public SpriteRenderer lineShow;

        public float[] positionX;
        public List<Note> nearJudgeNotes;
        Note[] nearNotes = new Note[10];

        public int nowMoveIndex, nowRotateIndex, nowAlphaIndex;


        void Awake()
        {
            lineShow.transform.localScale = new Vector3(lineShow.transform.localScale.x, 8.31f, lineShow.transform.localScale.z);
        }

        void Update()
        {
            UpdateJudgelinePosition();
            UpdateJudgelineRotation();
            UpdateJudgelineColor();
            UpdateSpeed();
        }

        public void UpdateSpeed()
        {
            speed = GetSpeed(LevelController.nowTime);
        }

        public float GetSpeed(double time)
        {
            for (int i = 0; i < speeds.Length; i++)
            {
                float? value = Utils.GetValueFromTimeAndValue(time, speeds[i].startTime, speeds[i].endTime, speeds[i].value, speeds[i].value);
                if (value != null)
                {
                    return (float)value;
                }
            }
            return 0;
        }

        public void UpdateJudgelinePosition()
        {
            Vector3 targetPos = Vector3.zero;
            for (int i = nowMoveIndex; i < moveEvents.Length; i++)
            {
                float startT = moveEvents[i].startTime;
                float endT = moveEvents[i].endTime;
                if (startT < LevelController.nowTime)
                {
                    nowMoveIndex = i;

                    float vs = moveEvents[i].start;
                    float ve = moveEvents[i].end;
                    float vs2 = moveEvents[i].start2;
                    float ve2 = moveEvents[i].end2;
                    targetPos.x = Utils.GetValueFromTimeAndValue(LevelController.nowTime, startT, endT, vs, ve);
                    targetPos.y = Utils.GetValueFromTimeAndValue(LevelController.nowTime, startT, endT, vs2, ve2);
                }
            }
            transform.localPosition = targetPos;
        }

        public void UpdateJudgelineRotation()
        {
            Vector3 targetRot = Vector3.zero;
            for (int i = nowRotateIndex; i < rotateEvents.Length; i++)
            {
                float startT = rotateEvents[i].startTime;
                if (startT < LevelController.nowTime)
                {
                    nowRotateIndex = i;
                    float endT = rotateEvents[i].endTime;
                    float vs = rotateEvents[i].start;
                    float ve = rotateEvents[i].end;
                    targetRot.z = Utils.GetValueFromTimeAndValue(LevelController.nowTime, startT, endT, vs, ve);
                }
            }
            transform.localEulerAngles = targetRot;
        }

        public void UpdateJudgelineColor()
        {
            //alpha = alphaEvents[nowAlphaIndex]
            for (int i = nowAlphaIndex; i < alphaEvents.Length; i++)
            {
                float startT = alphaEvents[i].startTime;
                if (startT < LevelController.nowTime)
                {
                    nowAlphaIndex = i;
                    float endT = alphaEvents[i].endTime;
                    float vs = alphaEvents[i].start;
                    float ve = alphaEvents[i].end;
                    alpha = Utils.GetValueFromTimeAndValue(LevelController.nowTime, startT, endT, vs, ve);
                }
            }
            Color color = new Color();
            if (LevelController.instance.FCAPState == LevelController.FCAP.AllPerfect) color = AP;
            else if (LevelController.instance.FCAPState == LevelController.FCAP.FullCombo) color = FC;
            else color = Color.white;
            color.a = alpha;
            lineShow.color = color;
        }

        public float GetSpeedDistance(double time)
        {
            float y = 0;
            float nowTime = (float)LevelController.nowTime;
            int index = speeds.Length - 1;
            for (int i = 0; i < speeds.Length; i++)
            {
                float start = speeds[i].startTime;
                float end = speeds[i].endTime;
                float value = speeds[i].value;
                if (start > time)
                {
                    index = i - 1;
                    break;
                }
                if (end > nowTime)
                {
                    if (start < nowTime)
                        y += (end - nowTime) * value;
                    else y += (end - start) * value;
                }
            }
            y -= (float)((speeds[index].endTime - time) * speeds[index].value);
            y /= 2;
            return y;
        }


    }
}